package com.example.demo.component;

import cn.hutool.core.io.FileUtil;
import com.example.demo.util.StreamUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class ThreadPool implements ExecutorService {

    private ExecutorService executorService;

    public ThreadPool() {
        this(Runtime.getRuntime().availableProcessors() * 10, Integer.MAX_VALUE, 30, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(), new ThreadPool.ColdThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());// 线程池的拒绝策略，默认是抛出异常
    }




    static class ColdThreadFactory implements ThreadFactory {
        private final static AtomicInteger poolNumber   = new AtomicInteger(1);
        private final        ThreadGroup   group;
        private final        AtomicInteger threadNumber = new AtomicInteger(1);
        private final        String        namePrefix;

        ColdThreadFactory() {
            SecurityManager s = System.getSecurityManager();
            group      = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
            namePrefix = group.getName() + "-cold-" + poolNumber.getAndIncrement() + "-thread-";
        }

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }


    /**
     * @param corePoolSize             核心线程数
     *                                 // 线程数 = 核数 * 期望CPU利用率 * 总时间(CPU计算时间 + 等待时间) / CPU计算时间
     *                                 // 例：4核CPU计算时间是50%，其它等待时间是50%，期望CPU被100%利用，套用公式：4 * 100% * 100% / 50% = 8
     *                                 // 例：4核CPU计算时间是10%，其它等待时间是90%，期望CPU被100%利用，套用公式：4 * 100% * 100% / 10% = 40
     * @param maximumPoolSize          最大的线程数
     * @param keepAliveTime            空闲线程最长的等待时间（当线程数大于内核数时，这是多余的空闲线程将在终止之前等待新任务的最长时间）
     * @param unit                     空闲线程最长的等待时间（当 maximumPoolSize > corePoolSize 时，这是多余的空闲线程将在终止之前等待新任务的最长时间）
     * @param workQueue                任务队列（用于在执行任务之前保留任务的队列。 此队列将仅保存execute方法提交的Runnable任务。）
     * @param threadFactory            线程工厂，用于创建线程的
     * @param rejectedExecutionHandler 当无可用线程以及任务队列满了时的拒绝任务的策略（因达到线程边界和队列容量而被阻止执行时使用的处理程序）
     */
    public ThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                      BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {
        executorService = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory, rejectedExecutionHandler);
    }

    public ThreadPool(ExecutorService executorService) {
        this.executorService = executorService;
    }

    @Override
    public void execute(Runnable runnable) {
        executorService.execute(runnable);
    }

    @Override
    public void shutdown() {
        executorService.shutdown();
    }

    @Override
    public List<Runnable> shutdownNow() {
        return executorService.shutdownNow();
    }

    @Override
    public boolean isShutdown() {
        return executorService.isShutdown();
    }

    @Override
    public boolean isTerminated() {
        return executorService.isTerminated();
    }

    @Override
    public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
        return executorService.awaitTermination(timeout, unit);
    }

    public <T> Future<T> submit(Callable<T> callable) {
        return executorService.submit(callable);
    }

    @Override
    public <T> Future<T> submit(Runnable task, T result) {
        return executorService.submit(task, result);
    }


    @Override
    public Future<?> submit(Runnable callable) {
        return executorService.submit(callable);
    }

    @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException {
        return executorService.invokeAll(tasks);
    }

    @Override
    public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException {
        return executorService.invokeAll(tasks, timeout, unit);
    }

    @Override
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException {
        return executorService.invokeAny(tasks);
    }

    @Override
    public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        return executorService.invokeAny(tasks, timeout, unit);
    }
}